/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springblade.modules.system.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.common.tool.UploadMinioUtil;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.File;
import org.springblade.modules.system.mapper.FileMapper;
import org.springblade.modules.system.service.IFileService;
import org.springblade.modules.system.vo.AttachmentVO;
import org.springblade.modules.system.vo.FileVO;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author Blade
 * @since 2022-07-12
 */
@Service
public class FileServiceImpl extends BaseServiceImpl<FileMapper, File> implements IFileService {
	@Resource
	private UploadMinioUtil uploadMinioUtil;

	@Override
	public IPage<FileVO> selectFilePage(IPage<FileVO> page, FileVO file) {
		return page.setRecords(baseMapper.selectFilePage(page, file));
	}

	@Override
	public File uploadFile(MultipartFile file) {
		return uploadFile(file, null,file.getOriginalFilename());
	}

	@Override
	public File uploadFile(MultipartFile file, String suffix, String fileName) {
		// 生成文件的唯一id
		Long fileId = IdWorker.getId();

		// 获取文件原始名称
		String originalFilename = fileName;

		// 获取文件后缀
		String fileSuffix = suffix;

		if (ObjectUtil.isNotEmpty(originalFilename)) {
			if (ObjectUtil.isEmpty(fileSuffix)) {
				fileSuffix = StrUtil.subAfter(originalFilename, ".", true);
			} else {
				originalFilename += "." + fileSuffix;
			}
		}
		// 生成文件的最终名称
		String dirName = DateTime.now().toString("yyyyMMdd");
		String finalName = dirName + "/" + fileId + "." + fileSuffix;

		// 计算文件大小kb
		Double fileSizeKb = Convert.toDouble(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024)).setScale(0, BigDecimal.ROUND_HALF_UP));
		File file1 = new File();
		if (uploadMinioUtil.upload(file, finalName)) {
			file1.setFileSize(fileSizeKb);
			file1.setFileName(finalName);
			file1.setOriginal(originalFilename);
			file1.setType(fileSuffix);
			file1.setBucketName("policy");
			save(file1);
		}
		return file1;
	}

	@Override
	public void downloadFile(String fileName, HttpServletResponse response) {
		LambdaQueryWrapper<File> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(File::getFileName, fileName);
		File one = getOne(queryWrapper);
		uploadMinioUtil.download(fileName, one.getOriginal(), response);
	}

	@Override
	public void downloadFileById(Long id, HttpServletResponse response) {
		LambdaQueryWrapper<File> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(File::getId, id);
		File one = getOne(queryWrapper);
		uploadMinioUtil.download(one.getFileName(), one.getOriginal(), response);
	}

	@Override
	public boolean deleteFile(String ids) {
		List<String> nameList = listByIds(Func.toLongList(ids)).stream().map(File::getFileName).collect(Collectors.toList());
		uploadMinioUtil.removeObjects(nameList);
		return deleteLogic(Func.toLongList(ids));
	}

	@Override
	public List<AttachmentVO> selectLibraryFiles(String fileIds, Long libraryId) {
		List<AttachmentVO> attachmentList = new ArrayList<>();
		List<FileVO> files = baseMapper.selectFileByIds(fileIds);
		if (files.size() > 0) {
			files.forEach(file -> {
				AttachmentVO attachmentVO = new AttachmentVO();
				attachmentVO.setFileId(file.getId());
				attachmentVO.setFileName(file.getOriginal());
				attachmentVO.setLibraryId(libraryId);
				attachmentList.add(attachmentVO);
			});
		}
		return attachmentList;
	}
}
